package com.itheima.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.Pojo.Goods;
import com.itheima.mapper.EsAddMapper;
import com.itheima.service.EsAddService;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class EsAddServiceImpl extends ServiceImpl<EsAddMapper,Goods> implements EsAddService {

    //初始化客户端
    private static RestHighLevelClient  client;

    /*
    * 初始化，连接客户端
    * */
    @PostConstruct
    public void init(){
        //创建rest客户端
        client = new RestHighLevelClient(RestClient.builder(
                //客户端连接资源，设置主机，http协议
                new HttpHost("192.168.200.129", 9200, "http")
        ));
    }

    /*
    * 初始化 创建索引库
    * */
    public void createIndex() throws IOException {
// 1. 创建CreateIndexRequest对象，并指定索引库名称
        CreateIndexRequest request = new CreateIndexRequest("goods");
//2. 指定settings配置
        Map map = new HashMap();
        map.put("number_of_shards", 2);
        map.put("number_of_replicas", 1);
        request.settings(map);

//3. 指定mapping配置
        request.mapping(
                "\n" +
                        "{\n" +
                        "    \"properties\": {\n" +

                        "      \"id\": {\n" +
                        "        \"type\": \"long\"\n" +
                        "      },\n" +

                        "      \"name\":{\n" +
                        "        \"type\": \"text\",\n" +
                        "        \"analyzer\": \"ik_smart\"\n" +
                        "      },\n" +

                        "      \"price\":{\n" +
                        "        \"type\": \"double\"\n" +
                        "      },\n" +

                        "      \"num\":{\n" +
                        "        \"type\": \"long\"\n" +
                        "      },\n" +

                        "      \"image\":{\n" +
                        "        \"type\": \"keyword\",\n" +
                        "        \"index\":\"false\"\n" +
                        "      },\n" +

                        "      \"images\":{\n" +
                        "        \"type\": \"keyword\",\n" +
                        "        \"index\":\"false\"\n" +
                        "      },\n" +

                        "      \"createTime\":{\n" +
                        "        \"type\": \"date\"\n" +
                        "      },\n" +

                        "      \"categoryId\":{\n" +
                        "        \"type\": \"long\"\n" +
                        "      },\n" +

                        "      \"categoryName\":{\n" +
                        "        \"type\": \"keyword\"\n" +
                        "      },\n" +

                        "      \"brandName\":{\n" +
                        "        \"type\": \"keyword\"\n" +
                        "      }\n" +
                        "    }\n" +
                        "}"
                ,XContentType.JSON);
//4. 发起请求，得到响应
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println("response = " + response.isAcknowledged());
    }

    @Override
    public String esAdd() throws IOException {

        //TODO 判断库是否已经创建
        //创建库
        createIndex();

        //1. 从数据库查询文档数据,检查数据

        //准备数据
//        List<Goods> goods = Arrays.asList(new Goods());
        List<Goods> goods = this.list();
        //2. 创建BulkRequest对象
        BulkRequest bulkRequest = new BulkRequest();
        //3. 创建多个IndexRequest对象，组织文档数据，并添加到BulkRequest中
        for (Goods good : goods) {
            bulkRequest.add(new IndexRequest("goods")
                    .id(good.getId())
                    .source(JSON.toJSONString(good), XContentType.JSON));

        }
        //4. 发起请求
        BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println("response = " + response.status());
        //todo
        return response.status().toString();
    }


    @PreDestroy
    public void destory(){
        try {
            if (client!=null){
                client.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<Goods> esFindAll() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(
                QueryBuilders.matchAllQuery()
        )
                .trackTotalHits(true);//设置显示总数 解除显示10000条限制
        SearchRequest request = new SearchRequest("goods");
        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        long total = response.getHits().getTotalHits().value;
        System.out.println("totalShards = " + total);
        SearchHit[] hits = response.getHits().getHits();
        List<Goods> list = new ArrayList<>();
        for (SearchHit hit : hits) {
            list.add(JSON.parseObject(hit.getSourceAsString(), Goods.class));
        }
        return list;
    }
}
